<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>导航守卫</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
  <div id="app">
    <h2>Hello Vue-Router!</h2>
    <p>
      <router-link to="/foo">Go to Foo</router-link>
      <br>
      <router-link to="/bar">Go to Bar</router-link>
      <br>
      <router-link to="/user/isok">Go to User-isok</router-link>
      <br>
      <router-link to="/user/love">Go to User-love</router-link>
      <br>
      <router-link to="/profile-love">Go to profile-love</router-link>
      <br>
      <router-link to="/profile-isok">Go to profile-isok</router-link>
    </p>
    <router-view></router-view>
  </div>

  <script>
    // 1. 定义路由组件
    const Foo = { template: '<div>foo</div>' };
    const Bar = { template: '<div>bar</div>' };
    const NotFound = { template: '<div>404</div>' };

    const Profile = { template: '<div>profile {{ $route.params.pathMatch }}</div>' };
    const User = { template: '<div>User {{ $route.params }}</div>' };

    // 2. 定义路由 「创建路由对象」
    const routes = [
      {
        path: '/foo',
        component: Foo,
      },
      {
        path: '/bar',
        component: Bar
      },
      {
        // 动态路径参数 以冒号开头
        path: '/user/:id',
        component: User
      },
      {
        path: '/profile-*',
        component: Profile,
        meta: {
          requireAuth: true
        }
      },
      {
        // `*` 通配符 匹配全部路由 「一般放在最后」
        path: '*',
        component: NotFound
      }
    ]

    // 3. 创建`router`实例, 然后传入`路由对象`进行配置
    const router = new VueRouter({
      mode: "history",
      routes
    })

    // 「全局前置守卫」
    router.beforeEach((to, from, next) => {
      // to: 即将要进入的目标「路由对象Route」
      // from: 当前导航正要离开的路由
      // next: 我们处理、解析完之后一定要调用此方法来触发「resolve」这个钩子, 否则就会一直卡在这出不去
      //  next() 进行管道中的下一个钩子, 如果钩子全部都执行完了, 则导航的状态就是「confirmed」确认的;
      //  next(false) 中断当前的导航, 如果浏览器的URL改变了（可能是用户手动或者浏览器后退按钮）, 那么URL地址会重置到`from`路由对应的地址;
      //  next('/') 或者 next({ path: '/' }) 跳转到一个不同的地址, 当前的导航被中断, 然后进行一个新的导航, 你可以向`next`传递任意位置对象,
      //  允许设置诸如`replace: true`、`name: 'home'`之类的选项以及任何用在`router-link`的to参数或`router.push`中的那些选项。
      //  next(error) v2.4.0+ 如果传入`next`的参数是一个`Error`实例, 那么则导航被终止且该错误会被传递给`router.onError()`注册过的回调
      console.group("「全局前置守卫」 =>");
      console.log("to =>", to);
      console.log("from =>", from);
      console.groupEnd();
      next();
    })

    // 4. 创建`Vue`实例, 将`router`挂载至Vue实例上
    const app = new Vue({
      router
    }).$mount('#app');
  </script>
</body>

</html>